package com.unience.ec2.eclipse.view;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.model.S3Bucket;
import org.jets3t.service.model.S3Object;
import org.jets3t.service.security.AWSCredentials;

import com.lowagie.text.pdf.codec.Base64.InputStream;
import com.unience.ec2.Util;
import com.unience.ec2.eclipse.config.Config;
import com.unience.ec2.eclipse.config.UtilSWT;

/**
 * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI
 * Builder, which is free for non-commercial use. If Jigloo is being used
 * commercially (ie, by a corporation, company or business for any purpose
 * whatever) then you should purchase a license for each developer using Jigloo.
 * Please visit www.cloudgarden.com for details. Use of Jigloo implies
 * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN
 * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR
 * ANY CORPORATE OR COMMERCIAL PURPOSE.
 */
public class S3ViewPart extends ViewPart implements MouseListener,
		SelectionListener {

	protected final Log log = LogFactory.getLog(this.getClass().getName());
	public static final String ID_VIEW = "com.unience.ec2.eclipse.view.S3ViewPart"; //$NON-NLS-1$

	private static final String REFRESH = "Refresh";
	private static final String UPLOAD = "Upload";
	private static final String DELETE = "Delete";
	private static final String NEW_BUCKET = "NewBucket";
	private static final String DOWNLOAD = "Download";
	private static final String START = "Start";
	private static final String SECURITY = "Acl";

	private static final String FOLDER = "_$folder$";

	HashMap<String, S3Object> folders = new HashMap<String, S3Object>();

	HashMap<String, S3Object> downloads = new HashMap<String, S3Object>();
	HashMap<String, S3Object> uploads = new HashMap<String, S3Object>();

	Composite composite1;

	private ToolItem toolItem1;
	private Table tableS3;
	private ToolBar toolBar;

	private AWSCredentials awsCredentials;
	private S3Service s3Service;

	private S3Bucket bucketActual;

	/**
	 * 
	 */
	public S3ViewPart() {
		super();

		// TODO Auto-generated constructor stub
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createPartControl(Composite parent) {
		{
			parent.setSize(871, 510);
		}
		composite1 = new Composite(parent, SWT.NULL);
		GridLayout composite1Layout = new GridLayout();
		composite1.setLayout(composite1Layout);
		{
			toolBar = new ToolBar(composite1, SWT.NONE);
			toolBar.setBounds(5, 5, 14, 14);
			{

				toolItem1 = new ToolItem(toolBar, SWT.NONE);
				ImageDescriptor descriptor = ImageDescriptor.createFromFile(
						Config.class, "start.png");
				toolItem1.setImage(descriptor.createImage());
				toolItem1.setText(START);
				toolItem1.addSelectionListener(this);

				toolItem1 = new ToolItem(toolBar, SWT.NONE);
				descriptor = ImageDescriptor.createFromFile(Config.class,
						"refresh.png");
				toolItem1.setImage(descriptor.createImage());
				toolItem1.setText(REFRESH);
				toolItem1.addSelectionListener(this);

				toolItem1 = new ToolItem(toolBar, SWT.NONE);
				descriptor = ImageDescriptor.createFromFile(Config.class,
						"folder_new.png");
				toolItem1.setImage(descriptor.createImage());
				toolItem1.setText(NEW_BUCKET);
				toolItem1.addSelectionListener(this);

				toolItem1 = new ToolItem(toolBar, SWT.NONE);
				descriptor = ImageDescriptor.createFromFile(Config.class,
						"action_remove.png");
				toolItem1.setImage(descriptor.createImage());
				toolItem1.setText(DELETE);
				toolItem1.addSelectionListener(this);

				toolItem1 = new ToolItem(toolBar, SWT.NONE);
				descriptor = ImageDescriptor.createFromFile(Config.class,
						"action_add.png");
				toolItem1.setImage(descriptor.createImage());
				toolItem1.setText(UPLOAD);
				toolItem1.addSelectionListener(this);

				toolItem1 = new ToolItem(toolBar, SWT.NONE);
				descriptor = ImageDescriptor.createFromFile(Config.class,
						"down.png");
				toolItem1.setImage(descriptor.createImage());
				toolItem1.setText(DOWNLOAD);
				toolItem1.addSelectionListener(this);

				toolItem1 = new ToolItem(toolBar, SWT.NONE);
				descriptor = ImageDescriptor.createFromFile(Config.class,
						"acl.png");
				toolItem1.setImage(descriptor.createImage());
				toolItem1.setText(SECURITY);
				toolItem1.addSelectionListener(this);
			}
		}
		{
			GridData tableS3LData = new GridData();
			tableS3LData.widthHint = 762;
			tableS3LData.heightHint = 404;
			tableS3 = new Table(composite1, SWT.BORDER);
			tableS3.setLayoutData(tableS3LData);

			TableColumn tc1 = new TableColumn(tableS3, SWT.LEFT);
			TableColumn tc2 = new TableColumn(tableS3, SWT.RIGHT);
			TableColumn tc3 = new TableColumn(tableS3, SWT.LEFT);

			tc1.setText("Name");
			tc2.setText("Size");
			tc3.setText("Date");

			tc1.setWidth(360);
			tc2.setWidth(180);
			tc3.setWidth(180);

			tableS3.setHeaderVisible(true);
			tableS3.addMouseListener(this);
		}

		Config config = Config.getInstance();

		awsCredentials = new AWSCredentials(config.getKeyId(), config
				.getSecretId());

		try {
			s3Service = new RestS3Service(awsCredentials);

			loadInit();
		} catch (S3ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void loadInit() {
		try {
			tableS3.removeAll();
			ImageDescriptor descriptorFolder = ImageDescriptor.createFromFile(
					Config.class, "folder.png");

			DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
			S3Bucket[] buckets = s3Service.listAllBuckets();

			for (S3Bucket bucket : buckets) {

				TableItem item = new TableItem(tableS3, SWT.NONE);
				item.setData(bucket);
				String formatedDate = bucket.getCreationDate().toString();
				item.setText(new String[] { bucket.getName(),
						bucket.getLocation(), formatedDate });
				item.setImage(descriptorFolder.createImage());

			}
		} catch (S3ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPart#setFocus()
	 */
	public void setFocus() {
		// TODO Auto-generated method stub
	}

	/**
	 * Cleans up all resources created by this ViewPart.
	 */
	public void dispose() {
		super.dispose();
	}

	public void mouseDoubleClick(MouseEvent e) {

		TableItem item[] = tableS3.getSelection();
		DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
		for (TableItem tableItem : item) {

			Object obj = tableItem.getData();

			if (obj instanceof S3Bucket) {
				S3Bucket bucket = (S3Bucket) obj;
				bucketActual = bucket;
				loadTable(bucket);
			}

			if (obj instanceof S3Object) {
				S3Object s3object = (S3Object) obj;

			}

		}

	}

	public void mouseDown(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	public void mouseUp(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	public void widgetDefaultSelected(SelectionEvent e) {
		// TODO Auto-generated method stub

	}

	public void widgetSelected(SelectionEvent e) {
		Object obj = e.getSource();

		if (obj instanceof ToolItem) {
			ToolItem toolItem = (ToolItem) obj;

			if (DELETE.equals(toolItem.getText())) {

				TableItem item = getSelectedItem();
				if (item != null) {
					Object data = item.getData();
					if (data instanceof S3Bucket) {
						S3Bucket bucket = (S3Bucket) data;

						try {
							s3Service.deleteBucket(bucket);
						} catch (S3ServiceException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
					if (data instanceof S3Object) {
						S3Object s3object = (S3Object) data;
						try {
							log.info("Deleting : " + s3object.getBucketName()
									+ " " + s3object.getKey());
							s3Service.deleteObject(bucketActual, s3object
									.getKey());
							loadTable(bucketActual);
						} catch (S3ServiceException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}

					}

				}

			}

			if (DOWNLOAD.equals(toolItem.getText())) {
				TableItem item = getSelectedItem();
				if (item != null) {
					Object data = item.getData();

					if (data instanceof S3Object) {
						org.eclipse.swt.widgets.FileDialog fd = new FileDialog(
								UtilSWT.getShell(), SWT.SAVE);
						fd.setText("Save");
						String[] filterExt = { "*.*" };
						fd.setFilterExtensions(filterExt);
						String selected = fd.open();
						System.out.println(selected);

						File file = new File(selected);

						if (!file.exists()) {
							try {
								file.createNewFile();
							} catch (IOException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
						}

						S3Object s3object = (S3Object) data;
						download(s3object, file);
					}

				}

			}

			if (UPLOAD.equals(toolItem.getText())) {

				upload();

			}

			if (NEW_BUCKET.equals(toolItem.getText())) {

			}

			if (START.equals(toolItem.getText())) {
				loadInit();
			}

			if (SECURITY.equals(toolItem.getText())) {

			}

			if (REFRESH.equals(toolItem.getText())) {
				loadTable(bucketActual);
			}

		}

	}

	private void loadTable(S3Bucket bucket) {
		try {
			ImageDescriptor descriptorFolder = ImageDescriptor.createFromFile(
					Config.class, "folder.png");

			ImageDescriptor descriptorFile = ImageDescriptor.createFromFile(
					Config.class, "file.png");

			S3Object[] objects = s3Service.listObjects(bucket);

			tableS3.removeAll();
			DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
			for (S3Object s3object : objects) {

				TableItem item1 = new TableItem(tableS3, SWT.NONE);
				item1.setData(s3object);

				String key = s3object.getKey();
				if (key.endsWith(FOLDER)) {
					item1.setImage(descriptorFolder.createImage());
					int i = key.indexOf(FOLDER);

					key = key.substring(0, i);
					if (!folders.containsKey(key)) {
						folders.put(key, s3object);
					}

				} else {
					item1.setImage(descriptorFile.createImage());
				}

				String formatedDate = bucket.getCreationDate().toString();
				item1.setText(new String[] { key,
						new String("" + s3object.getContentLength()),
						formatedDate });

			}

		} catch (S3ServiceException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	private TableItem getSelectedItem() {
		TableItem item[] = tableS3.getSelection();
		for (TableItem tableItem : item) {

			return tableItem;

		}

		return null;
	}

	private void download(S3Object obj, File file) {

		DownLoad downLoad = new DownLoad(obj, composite1, bucketActual, file);

		downloads.put(obj.getKey(), obj);

		downLoad.start();

	}

	private void upload() {

		FileDialog fd = new FileDialog(UtilSWT.getShell(), SWT.OPEN);
		fd.setText("Open");
		// fd.setFilterPath("C:/");
		String[] filterExt = { "*.*" };
		fd.setFilterExtensions(filterExt);
		String selected = fd.open();
		System.out.println(selected);

		File file = new File(selected);

		if (file.exists()) {
			Upload upLoad = new Upload(file, composite1, bucketActual);

			uploads.put(file.getPath(), null);

			upLoad.start();

		}

	}

	class DownLoad extends Thread {

		File file;
		S3Object obj;
		S3Bucket bucket;
		Composite composite;
		ProgressBar pb;

		DownLoad me;

		long l = 0;

		public void update(int increment) {
			if (pb == null) {
				pb = new ProgressBar(composite, SWT.SMOOTH);

			}

			composite.layout();

			pb.setSelection(increment);

		}

		public void run() {
			try {
				S3Object objectComplete = s3Service.getObject(bucket, obj
						.getKey());
				System.out.println("S3Object, complete: " + objectComplete);

				me = this;
				int progres = 0;

				long size = obj.getContentLength();

				long readed = 0;

				java.io.InputStream reader = objectComplete
						.getDataInputStream();
				byte[] data = new byte[1024 * 50];
				int i = 0;

				FileOutputStream fileOut = new FileOutputStream(file);

				while ((i = reader.read(data)) != -1) {
					fileOut.write(data, 0, i);
					readed = readed + i;
					l = (readed * 100) / size;
					Config.getInstance().getDisplay().asyncExec(new Runnable() {
						public void run() {

							final IWorkbench workbench = PlatformUI
									.getWorkbench();
							if (workbench == null)
								return;
							final Display display = workbench.getDisplay();

							if (!display.isDisposed()) {

								me.update((int) l);
							}
						}
					});

				}
			} catch (S3ServiceException e) {
				e.printStackTrace();
			} catch (IOException e) {

				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		public DownLoad(S3Object obj, Composite composite, S3Bucket bucket,
				File f) {
			this.file = f;
			this.obj = obj;
			this.composite = composite;
			this.bucket = bucket;
		}

	}

	class Upload extends Thread {

		File file;
		S3Bucket bucket;
		Composite composite;
		ProgressBar pb;

		Upload me;

		long l = 0;

		public void update(int increment) {
			if (pb == null) {
				pb = new ProgressBar(composite, SWT.SMOOTH);

			}

			composite.layout();

			pb.setSelection(increment);

		}

		public void run() {
			
		
			try {
				S3Object fileObject = new S3Object(bucket, file);
				
				s3Service.putObject(bucket, fileObject);

			}catch(S3ServiceException e){
				e.printStackTrace();	
			}catch (FileNotFoundException e) {
				e.printStackTrace();
				// TODO Auto-generated catch block
			
			}

			
			
			/*
			 * try { S3Object objectComplete = s3Service.getObject(bucket, obj
			 * .getKey()); System.out.println("S3Object, complete: " +
			 * objectComplete);
			 * 
			 * me = this; int progres = 0;
			 * 
			 * long size = obj.getContentLength();
			 * 
			 * long readed = 0;
			 * 
			 * java.io.InputStream reader = objectComplete.getDataInputStream();
			 * byte[] data = new byte[1024*25]; int i = 0; while ((i =
			 * reader.read(data)) != -1) { System.out.println(data); readed =
			 * readed + i; l = (readed * 100) / size;
			 * Config.getInstance().getDisplay().asyncExec(new Runnable() {
			 * public void run() {
			 * 
			 * final IWorkbench workbench = PlatformUI .getWorkbench(); if
			 * (workbench == null) return; final Display display =
			 * workbench.getDisplay();
			 * 
			 * if (!display.isDisposed()) {
			 * 
			 * me.update((int) l); } } });
			 *  } } catch (S3ServiceException e) { e.printStackTrace(); } catch
			 * (IOException e) {
			 *  // TODO Auto-generated catch block e.printStackTrace(); }
			 */
		}

		public Upload(File f, Composite composite, S3Bucket bucket) {
			this.file = f;
			this.composite = composite;
			this.bucket = bucket;
		}

	}

}
